#ifndef ML_MODEL_H
#define ML_MODEL_H

// Context

#ifdef JMBC_INSIDE

#include <Core/clCore.h>

typedef struct
{
	int magic;
	unsigned int bones;
	unsigned int parents;
	unsigned int vertices;
	unsigned int materials;
	unsigned int faces;
	unsigned int tags;
	unsigned int weights;
	unsigned int frames;
	unsigned int actions;
} MLModelHeader;

typedef struct
{
	unsigned int start;
	unsigned int parents;
} MLModelBone;

typedef struct
{
	unsigned int bone;
} MLModelParent;

typedef struct
{
	float coord[3];
	float normal[3];
	unsigned int start;
	unsigned int weights;
} MLModelVertex;

typedef struct
{
	wchar_t name[TL_STRING_DEFAULT_FIXED_SIZE];
	unsigned int start;
	unsigned int faces;
} MLModelMaterial;

typedef struct
{
	unsigned int vertices[3];
	float normal[3];
	float texcoords[3][2];
} MLModelFace;

typedef struct
{
	int bone;
	float value;
} MLModelWeight;

typedef struct
{
	wchar_t name[TL_STRING_DEFAULT_FIXED_SIZE];
	float matrix[16];
	unsigned int start;
	unsigned int weights;
} MLModelTag;

typedef struct
{
	float matrix[16];
} MLModelFrame;

typedef struct
{
	wchar_t name[TL_STRING_DEFAULT_FIXED_SIZE];
	unsigned int start;
	unsigned int frames;
} MLModelAction;

#define ML_MODEL_GROUP_BONES 0
#define ML_MODEL_GROUP_PARENTS 1
#define ML_MODEL_GROUP_VERTICES 2
#define ML_MODEL_GROUP_MATERIALS 3
#define ML_MODEL_GROUP_FACES 4
#define ML_MODEL_GROUP_TAGS 5
#define ML_MODEL_GROUP_WEIGHTS 6
#define ML_MODEL_GROUP_FRAMES 7
#define ML_MODEL_GROUP_ACTIONS 8
#define ML_MODEL_GROUP_ANIM 9

typedef struct
{
	unsigned int groups[10];

	unsigned int action, frame;

	unsigned int materials;

	float matrix[16];
} MLModel;

#endif

void
mlModelCreateContext(void);

// Generation / Deletion
void
mlGenModels(unsigned int n, unsigned int *models);

void
mlDeleteModels(unsigned int n, unsigned int *models);

// Load / Unload
void
mlModelLoad(unsigned int id, unsigned int filepath);

void
mlModelUnload(unsigned int id);

void
mlModelsUnload(unsigned int n, unsigned int *models);

// Operation

void
mlModelCompile(unsigned int id, unsigned int filepath);

void
mlModelDecompile(unsigned int id, unsigned int filepath);

unsigned int
mlModelBones(unsigned int id);

unsigned int
mlModelParents(unsigned int id);

unsigned int
mlModelVertices(unsigned int id);

unsigned int
mlModelMaterials(unsigned int id);

unsigned int
mlModelMaterial(unsigned int id, unsigned int name);

unsigned int
mlModelMaterialMaterial(unsigned int id, unsigned int material);

unsigned int
mlModelFaces(unsigned int id);

unsigned int
mlModelTags(unsigned int id);

unsigned int
mlModelTag(unsigned int id, unsigned int name);

void
mlModelTagMatrix(unsigned int id, unsigned int tag, float matrix[16]);

unsigned int
mlModelWeights(unsigned int id);

unsigned int
mlModelFrames(unsigned int id);

unsigned int
mlModelActions(unsigned int id);

unsigned int
mlModelAction(unsigned int id, unsigned int name);

unsigned int
mlModelActionFrames(unsigned int id, unsigned int action);

void
mlModelActionSet(unsigned int id, unsigned int action);

void
mlModelActionFrameSet(unsigned int id, unsigned int frame);

float *
mlModelMatrix(unsigned int id);

// Disk I/O

void
mlModelSave(unsigned int id, unsigned int filepath);

void
mlModelGenMaterials(unsigned int id, unsigned int path);

void
mlModelDeleteMaterials(unsigned int id);

// OpenGL Integration

void
mlModelDraw(unsigned int id);

//void
//mlModelDrawTag(unsigned int id, unsigned int action, unsigned int frame, unsigned int tag, unsigned int submodel, unsigned int subtextures, unsigned int subaction, unsigned int subframe);

//void
//mlModelFrustumDraw(unsigned int id, unsigned int textures, unsigned int frustum, unsigned int action, unsigned int frame);

#endif
